package game.phases.actionphase 
{
	import game.mapviewer.popups.losses.LossesPopup;
	import game.phases.actionphase.commands.BattleCommand;
	import game.unitmanager.ArmyController;
	import game.unitmanager.OrderTypes;
	/**
	 * ...
	 * @author rnk
	 */
	public class MarchSolver extends Solver
	{
		private var movingArmies:Array;
		private var currentArmyIdx:int;
		
		public function MarchSolver() 
		{
			
		}
		
		override public function Enter():void 
		{
			//prepare
			papa.papa.mapView.SetArmiesMouseListeners(false);
			papa.papa.mapView.LockArmies(true, 0, true);
			
			StartOver();
			
		}
		
		private function StartOver():void
		{
			//get marching armies list
			RefreshArmiesList();
			
			//if no armies then skip solver
			if (movingArmies.length == 0)
			{
				Finish();
				return;
			}
			
			//give controls to first moving army
			currentArmyIdx = 0;
			GiveControlToArmy(currentArmyIdx);
		}
		
		private function GiveControlToArmy(idx:int):void 
		{
			currentArmyIdx = idx;
			var army:ArmyController = movingArmies[idx];
			
			//skip if army has no order
			if (army.order != OrderTypes.MARCH)
			{
				OnArmyFinished();
				return;
			}
			
			//show player name
			papa.papa.gui.SetCurrentPlayer(papa.papa.GetPlayer(army.loyalty));
			
			//select province to move
			papa.papa.mapView.SelectProvinceToMarch(army.model.province.uid, OnTargetSelected);
			
		}
		
		private function OnTargetSelected(provinceUid:String):void
		{
			//get current army
			var currentArmy:ArmyController = (movingArmies[currentArmyIdx] as ArmyController);
			
			//clear order
			currentArmy.SetOrder( -1);
			
			//if we dont move then this army finishes
			if (provinceUid == currentArmy.model.province.uid)
			{
				OnArmyFinished();
				return;
			}
			
			//get army at the destination
			var armyAtDestination:ArmyController = papa.papa.unitsManager.GetArmy(provinceUid);
			
			//if no army
			if (!armyAtDestination)
			{
				//just move there
				currentArmy.MoveTo(provinceUid, 
					function():void
					{
						OnArmyFinished();
					}
				);
				return;
			} 
			else
			//if there is army
			{
				//if they are friendly, join
				if (armyAtDestination.loyalty == currentArmy.loyalty)
				{
					currentArmy.MoveTo(provinceUid, 
						function():void
						{
							OnArmyFinished();
						}
					);
					return;
				}
				else
				{
					//if they are hostile or neutral, attack
					var attackCommand:BattleCommand = new BattleCommand(currentArmy, armyAtDestination);
					attackCommand.papa = this;
					attackCommand.callback = OnBattleFinished;
					attackCommand.Execute();
					return;
				}
			}
			
			OnArmyFinished();
			
		}
		
		private function OnBattleFinished(attackerResult:Object, defenderResult:Object):void
		{
			//start over becos some of the armies could be destroyed
			StartOver();
		}
		
		private function OnArmyFinished():void
		{
			papa.papa.gui.SetCurrentPlayer(null);
			
			currentArmyIdx++;
			if (currentArmyIdx < movingArmies.length)
			{
				GiveControlToArmy(currentArmyIdx);
			} else
			{
				Finish();
			}
		}
		
		override public function Exit():void 
		{
			
			
			
		}
		
		private function RefreshArmiesList():void
		{
			//get all armies
			var allArmies:Array = papa.papa.unitsManager.GetArmies();
			
			//get moving and not neutral armies
			movingArmies = [];
			for each (var armyController:ArmyController in allArmies) 
			{
				if (armyController.order == OrderTypes.MARCH && armyController.loyalty != 0 )
				{
					movingArmies.push(armyController);
				}
			}
			
			//sort by initiative
			movingArmies.sort(
				function(armyA:ArmyController, armyB:ArmyController):Number
				{
					var priceA:Number = armyA.GetInitiative();
					var priceB:Number = armyB.GetInitiative();
					
					if (priceA > priceB) return 1;
					if (priceA < priceB) return -1;
					return 0;
				}
			);			
		}
		
		
	}

}